/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controle;

import Entidades.Link;
import Entidades.LocalizadoraDeNos;
import Entidades.LocalizadoraLinks;
import Entidades.No;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JOptionPane;
import limite.Apresentacao;

/**
 *
 * @author adriano
 */
public class Genetico {
    
    private static limite.Apresentacao tela;
    
    private double distancia = 0;
    private ArrayList<No> nos = new ArrayList<No>();
    private ArrayList<Link> links = new ArrayList<Link>();
    private ArrayList<Rota> rotas= new ArrayList<Rota>();
    private ArrayList<Object> rota= new ArrayList<Object>();

    private ArrayList<No> genetico() {
        
        //Cria a matris de distancias com o tamanho referente a quantidade de nós        
        nos = LocalizadoraDeNos.getLista();
        insereLinks();
                
//        links = ControleLinks.getTodosLinks();

//        matrizP = getMatrizP(nos, links);
//        matrizD = getMatrizDistancia(nos, links);
//
//        executaFloyd();
        return null;
    }
        
    public void executa(Apresentacao apresentacao, int iteracoes, int populacao, int crossover, int mutação) {    
        tela = apresentacao;
        geraPopulação(populacao);
        
        for (int i = 0; i < iteracoes; i++) {
            ArrayList<No> rota = genetico();
            
            if (rota == null) {
                System.out.println("Algoritmo não foi capaz e idetificar o melhor caminho!");
                return;
            } 
            
            double distanciaParcial = ControleNos.distancia(rota);
            if (distancia == 0 || distancia > distanciaParcial){
                distancia = distanciaParcial;
                
                //preencge campo menor distância
                tela.insereMelhorDistânciaGenetico(distancia);
                //apresentação dos resultados na tela
                marcaDistancias();
                tela.atualiza();
                marcaCaminhoMinimo(rota);
                tela.atualiza();
            }
            
        }
        
    }
    
    //utilizado para marcar o tamanho de cada link na tela
    private static void marcaDistancias(){
        ArrayList<Link> links = LocalizadoraLinks.getLista();
        for(int i = 0; i < links.size(); i++){
            Link l=(Link)LocalizadoraLinks.getLink(i);
            No origem=l.getOrigem();
            No destino=l.getDestino();
            tela.registraDistancia(origem.getIdentificador(),destino.getIdentificador(),ControleNos.calculaDistancia(origem, destino));
        }
    }
    
    //utilizado para destacar o caminho escolhido na tela
    private static void marcaCaminhoMinimo(ArrayList<No> rota) {
        for (int i = 0; i < rota.size(); i++) {
            try {
                No origem = (No) rota.get(i);
                No destino = (No) rota.get(i + 1);
                tela.marcaCaminho(origem.getIdentificador(), destino.getIdentificador());
            } catch (Exception e) {
                JOptionPane.showMessageDialog(tela, "Erro ao marcar o caminho!");
                System.out.println("Erro ao marcar o caminho!");
            }
        }
    }

    private void insereLinks() {
        int numNos = nos.size();

        for (int origem = 1; origem <= numNos; origem++) {
            for (int destino = origem + 1; destino <= numNos; destino++) {
                tela.insereLink(origem, destino, Color.GRAY);
                tela.registraDistancia(origem, destino, ControleNos.calculaDistancia(Entidades.LocalizadoraDeNos.busca(origem),
                        Entidades.LocalizadoraDeNos.busca(destino)));
                tela.atualiza();
            }
        }
    }

    /**
     * Gera as rotas na primera iteração.
     * @param populacao 
     */
    private void geraPopulação(int populacao) {
        for (int i = 0; i < populacao; i++) {
            rota.add(nos);
        }
        
//        rotas.add(new Rota(nos));       
//                
//        for (int i = 1; i < populacao; i++) {
//            Rota rota = new Rota(nos);            
//            rota.embaralha();
//            rotas.add(rota);
//            System.out.println("********** " + i);
//            rota = new Rota();
//        }
    }        
        

}
